package com.hyzh.latte.vehicle.nezha;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.hyzh.latte.vehicle.dmo.entity.CameraPGEntity;
import com.hyzh.latte.vehicle.dmo.entity.GatePGEntity;
import com.hyzh.latte.vehicle.dmo.entity.PolePGEntity;
import lombok.Getter;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * TODO 杆子 和 杆子 关系 最好是 从算法组 获取；  这样 才会更准确
 *
 * @author songkui
 * @since 2024/3/19 16:00
 */
public class NezhaDeviceManager {

    @Getter
    private  ParkDeviceBuilder builderData;
    //key parkCode;
    private final Map<String, ParkPoleGraph> parkCameraMapping = new HashMap<>();

    private NezhaDeviceManager() {
    }

    private static final class ManagerHolder {
        static final NezhaDeviceManager manager = new NezhaDeviceManager();
    }

    public static NezhaDeviceManager getInstance() {
        return ManagerHolder.manager;
    }


    /**
     * 1，查询数据库数据转换生成； 2， 如果数据有变动，那么需要同步更新数据【最好是晚上更新数据】
     *
     * @param parkDeviceBuilder :;
     */

    public void initialize(ParkDeviceBuilder parkDeviceBuilder) throws Exception {

        this.builderData = parkDeviceBuilder;

        if (CollectionUtil.isEmpty(parkDeviceBuilder.getPoleMap()) || CollectionUtil.isEmpty(parkDeviceBuilder.getPoleEdgeMap())) {
            throw new Exception("Park pole or path is null");
        }
        for (Map.Entry<String, List<PoleEdge>> entry : parkDeviceBuilder.getPoleEdgeMap().entrySet()) {
            String park = entry.getKey();
            buildParkPoleGraph(park,  entry.getValue(), parkDeviceBuilder.getCameraMap().get(park), parkDeviceBuilder.getGateMap().get(park), parkDeviceBuilder.getPoleEntityMap().get(park));
            NezhaPersonManager.getInstance().initPersonSchedule(park, parkDeviceBuilder.getParkEntityMap().get(park), parkDeviceBuilder.getNezhaRecordService()); //person track
        }

    }

    public void buildParkPoleGraph(String parkCode, List<PoleEdge> poleEdgeList, Map<String, CameraPGEntity> cmap, Map<String, GatePGEntity> gateMap, Map<String, PolePGEntity> polePGEntityMap) throws Exception {
        ParkPoleGraph parkCameraGraph = new ParkPoleGraph(parkCode);
        parkCameraGraph.initializePoleGraph(poleEdgeList, cmap, gateMap, polePGEntityMap);
        parkCameraMapping.put(parkCode, parkCameraGraph);
    }

    public PoleVertex  getPoleVertexByPoleCode(String parkCode, String poleCode, String lab){
        if (StrUtil.isEmpty(poleCode)){
            return null;
        }

        ParkPoleGraph graph = parkCameraMapping.get(parkCode);
        return  null == graph ? null : graph.getPoleVertexByPoleCode(poleCode, lab);
    }

    public List<PoleVertex> findVertexPaths(String parkCode, PoleVertex start, PoleVertex end){
        ParkPoleGraph graph = parkCameraMapping.get(parkCode);
        return  null == graph ? null : graph.findVertexPaths(start, end);
    }

    public  List<PoleEdge> findEdgePaths(String parkCode, PoleVertex start, PoleVertex end){
        ParkPoleGraph graph = parkCameraMapping.get(parkCode);
        return  null == graph ? null : graph.findEdgePaths(start, end);
    }

    //首先 get camera   跟camera 属性 + 算法方向  判断 车辆 车道
    public PoleVertex getPoleVertexByCameraCode(String parkCode, String cno, int dit){
        ParkPoleGraph graph = parkCameraMapping.get(parkCode);
        return  null == graph ? null : graph.getPoleVertexByCameraCode(cno, dit);
    }
    public PoleVertex getPoleVertexByGateNo(String parkCode, String gateNo){
        ParkPoleGraph graph = parkCameraMapping.get(parkCode);
        return  null == graph ? null : graph.getPoleVertexByGateNo(gateNo);
    }

    //需要判断岔路口
    public PoleVertex getNextByVertex(String parkCode, PoleVertex vertex){
        ParkPoleGraph graph = parkCameraMapping.get(parkCode);
        return null == graph || vertex.isFork() ? null : graph.getNextNode(vertex);
    }

    //排除掉头
    public PoleVertex getNextNodeByDit(String parkCode, PoleVertex vertex, int dit){
        if (null == vertex){
            return null;
        }
        ParkPoleGraph graph = parkCameraMapping.get(parkCode);
        return null == graph  ? null : graph.getNextNodeByDit(vertex, dit);
    }

    public String getCameraCodeByPoleCode(String parkCode, String poleCode){
        ParkPoleGraph graph = parkCameraMapping.get(parkCode);
        return null == graph ? null : graph.getCameraCodeByPoleCode(poleCode);
    }

    public GatePGEntity getGatePGEntityByGateNo(String parkCode, String gateNo){
        ParkPoleGraph graph = parkCameraMapping.get(parkCode);
        return null == graph ? null : graph.getGatePGEntityByGateNo(gateNo);
    }
    public PolePGEntity getPolePGEntityByPoleCode(String parkCode, String poleCode){
        ParkPoleGraph graph = parkCameraMapping.get(parkCode);
        return null == graph ? null : graph.getPolePGEntityByPoleCode(poleCode);
    }


}
